<?php
/**
 * @version $Id: tag.creator.class.php 3 2010-05-25 14:59:16Z vladzimirs $
 * @package UnoCloud
 * @copyright Авторские права (C) 2009-2010 UnoCloud team & (C) 2007-2010 Joostina team &. Все права защищены.
 * @license Лицензия http://www.gnu.org/licenses/gpl-2.0.htm GNU/GPL, или help/license.php
 * UnoCart! - свободное программное обеспечение распространяемое по условиям лицензии GNU/GPL
 * Для получения информации о используемых расширениях и замечаний об авторском праве, смотрите файл help/copyright.php.
 */

defined('_VALID_MOS') or die('Direct Access to this location is not allowed.');

function UNOCLOUD_trim_value(&$value)
{
    $value = Jstring::trim($value);
}


class UnoCloud_TagCreator
{

    var $UNOCLOUD_config = null;
    var $encoding = null;////Удалить
    var $entity_encoding = null;////Удалить
    var $lastTime = null;
    var $debug = 0;
    var $correctPHP = null;
    var $UNOCLOUD_key_preg_replace = null;
    var $UNOCLOUD_preg_replace = null;
    var $UNOCLOUD_cache = true;
    var $UNOCLOUD_startMem = 0;
    var $UNOCLOUD_excluded = null;
    var $UNOCLOUD_tag = array();
    var $UNOCLOUD_key = array();
    var $UNOCLOUD_key_asword = 0;
    var $UNOCLOUD_min_counter = 0;
    var $UNOCLOUD_key_min_counter = 0;
    var $UNOCLOUD_published = 0;
    var $UNOCLOUD_key_published = 0;

    function UnoCloud_TagCreator($UNOCLOUD_config)
    {
        $this->UNOCLOUD_config = $UNOCLOUD_config;
        $this->lastTime = $this->getmicrotime();
        //$this->correctPHP = $this->correctPHPversion();
        $this->UNOCLOUD_key_preg_replace = $this->UNOCLOUD_config->getValue("UNOCLOUD_key_preg_replace");
        $this->UNOCLOUD_preg_replace = $this->UNOCLOUD_config->getValue("UNOCLOUD_preg_replace");
        $this->UNOCLOUD_startMem = memory_get_usage();
        $UNOCLOUD_blacklist = $this->UNOCLOUD_config->getValue("UNOCLOUD_blacklist");
        $this->UNOCLOUD_excluded = explode(",", preg_replace("/[.\-:><()!?\n]/", " ", $UNOCLOUD_blacklist));
        $this->trim_array($this->UNOCLOUD_excluded);
        if ($this->UNOCLOUD_config->getValue("UNOCLOUD_on_cache") != null)
            $this->UNOCLOUD_cache = $this->UNOCLOUD_config->getValue("UNOCLOUD_on_cache");
        $this->UNOCLOUD_key_asword = $this->UNOCLOUD_config->getValue("UNOCLOUD_key_asword");
        $this->UNOCLOUD_min_counter = $this->UNOCLOUD_config->getValue("UNOCLOUD_min_counter");
        $this->UNOCLOUD_key_min_counter = $this->UNOCLOUD_config->getValue("UNOCLOUD_key_min_counter");
        $this->UNOCLOUD_published = $this->UNOCLOUD_config->getValue("UNOCLOUD_published");
        $this->UNOCLOUD_key_published = $this->UNOCLOUD_config->getValue("UNOCLOUD_key_published");
    }

    function getmicrotime()
    {
        list($usec, $sec) = explode(" ", microtime());
        return ((float)$usec + (float)$sec);
    }

    function memUsage($level)
    {
        $memus = memory_get_usage();
        $mem = $memus - $this->UNOCLOUD_startMem;
        $this->UNOCLOUD_startMem = $memus;
        $mem = round($mem / 1000, 2);
        echo (UNOCLOUD_MEMUS . "( " . $level . " )" . $mem . " KB <br>");
    }

    function runTime($level)
    {
        if ($this->debug) {
            $time_end = $this->getmicrotime();
            $time = $time_end - $this->lastTime;
            $this->lastTime = $time_end;
            $time = round($time, 6);
            $time = UNOCLOUD_GENTIME . "( " . $level . " ) : " . $time . " s<br>";
            echo ($time);
            $this->memUsage($level);
        }
    }

    function addWord(&$tags)
    {
        if (!empty($tags)) {
            foreach ($tags as $word => $counter) {
                $word = Jstring::trim($word);
                if (($this->checkWord($word, $this->UNOCLOUD_excluded)) && ($counter >= $this->
                    UNOCLOUD_min_counter)) {
                    $this->saveWord($word, $counter, 0, $this->UNOCLOUD_published, 1);
                }
            }
            unset($tags);
        }
    }


    function addKeyWord(&$tags)
    {
        if (!empty($tags)) {
            foreach ($tags as $word => $counter) {
                $word = Jstring::trim($word);
                if (($this->checkWord($word, $this->UNOCLOUD_excluded)) && ($counter >= $this->
                    UNOCLOUD_key_min_counter)) {
                    $this->saveWord($word, $counter, 0, $this->UNOCLOUD_key_published, 2);
                }
            }
            unset($tags);
        }
    }

    function addKey(&$metaKeys)
    {
        if (!empty($metaKeys)) {
            foreach ($metaKeys as $key => $counter) {
                $key = Jstring::trim($key);
                if (($this->checkKey($key, $this->UNOCLOUD_excluded)) && ($counter >= $this->
                    UNOCLOUD_key_min_counter)) {
                    $this->saveWord($key, $counter, 0, $this->UNOCLOUD_key_published, 2);
                }
            }
            unset($metaKeys);
        }
    }

    function cacheTag(&$stag, &$metaKey)
    {
        if ($this->UNOCLOUD_cache) {
            if (!empty($stag)) {

                $this->validate($stag);
                $stag = Jstring::strtolower($stag);

                $tags = explode(" ", $stag);
                unset($stag);
                $this->trim_array($tags);
                $tags = array_count_values($tags);
                foreach ($tags as $word => $counter) {
                    if (!empty($word)) {
                        if (!empty($this->UNOCLOUD_tag[$word])) {
                            $tempCounter = $this->UNOCLOUD_tag[$word];
                        } else
                            $tempCounter = 0; //patch 20080725

                        $this->UNOCLOUD_tag[$word] = $counter + $tempCounter;
                    }
                }
            }


            if (!empty($metaKey)) {
                if ($this->UNOCLOUD_key_asword) {
                    $this->validate($metaKey);
                    $metaKey = Jstring::strtolower($metaKey);
                    $metaKeys = explode(" ", $metaKey);
                } else {
                    $this->validate_key($metaKey);
                    $metaKey = Jstring::strtolower($metaKey);
                    $metaKeys = explode(",", $metaKey);
                }
                unset($metaKey);
                $this->trim_array($metaKeys);
                $metaKeys = array_count_values($metaKeys);

                foreach ($metaKeys as $key => $counter) {
                    if (!empty($key)) {
                        if (!empty($this->UNOCLOUD_key[$key])) {
                            $tempCounter = $this->UNOCLOUD_key[$key];
                        } else
                            $tempCounter = 0;
                        $this->UNOCLOUD_key[$key] = $counter + $tempCounter;
                    }
                }
            }

            return true;
        }
        return false;
    }

    function createCloudArray()
    {
        global $database, $mosConfig_absolute_path, $mosConfig_dbprefix;
        if ($this->debug) {
            if ($this->UNOCLOUD_cache)
                $isCache = UNOCLOUD_YES;
            else
                $isCache = UNOCLOUD_NO;
            echo ("PHP= " . phpversion() . "<br> UnoCloud cache = " . $isCache . "<br>");
        }
        $this->resetStat();
        $stag = " ";
        $metaKey = " ";
        $database->setQuery("UPDATE #__unocloud_stat SET new=0");
        $database->query();
        $this->runTime("Start");
        $this->loadPlugins($stag, $metaKey);
        //$this->runTime("Plugins");


        if ($this->UNOCLOUD_cache) {
            $this->addWord($this->UNOCLOUD_tag);
            $this->runTime("Words");
            if ($this->UNOCLOUD_config->getValue("UNOCLOUD_key_asword"))
                $this->addKeyWord($this->UNOCLOUD_key);
            else
                $this->addKey($this->UNOCLOUD_key);

        } else {
            //word
            if ((!empty($stag)) && ($this->UNOCLOUD_config->getValue("UNOCLOUD_enabled") > 0)) {


                $this->validate($stag);
                $stag = Jstring::strtolower($stag);

                $tags = explode(" ", $stag);
                unset($stag);
                $this->trim_array($tags);
                $tags = array_count_values($tags);
                $this->addWord($tags);
                $this->runTime("Words");
            }
            //key
            if ((!empty($metaKey)) && ($this->UNOCLOUD_config->getValue("UNOCLOUD_key_enabled") >
                0)) {
                if ($this->UNOCLOUD_config->getValue("UNOCLOUD_key_asword")) {
                    $this->validate($metaKey);
                    $metaKey = Jstring::strtolower($metaKey);
                    $tags = explode(" ", $metaKey);
                    unset($metaKey);
                    $this->trim_array($tags);
                    $tags = array_count_values($tags);
                    $this->addKeyWord($tags);
                } else {
                    $this->validate_key($metaKey);
                    $metaKey = Jstring::strtolower($metaKey);
                    $metaKeys = explode(",", $metaKey);
                    unset($metaKey);
                    $this->trim_array($metaKeys);
                    $metaKeys = array_count_values($metaKeys);
                    $this->addKey($metaKeys);
                }
            }

        }
        $this->runTime("Keys");
        $this->addWhiteList();
        $this->runTime("Whitelist");
        $this->setFontSize();
        $this->runTime("Font size");
        $this->eraseZeroCounter();
        $this->runTime("Erase 0 counter");
    }

    function addWhiteList()
    {
        global $database;

        $UNOCLOUD_whitelist = $this->UNOCLOUD_config->getValue("UNOCLOUD_whitelist");
        $UNOCLOUD_min_counter = $this->UNOCLOUD_config->getValue("UNOCLOUD_min_counter");
        $UNOCLOUD_key_whitelist = $this->UNOCLOUD_config->getValue("UNOCLOUD_key_whitelist");
        $UNOCLOUD_key_min_counter = $this->UNOCLOUD_config->getValue("UNOCLOUD_key_min_counter");

        if ((!empty($UNOCLOUD_whitelist)) && ($this->UNOCLOUD_config->getValue("UNOCLOUD_enabled") >
            0)) {
            $this->validate($UNOCLOUD_whitelist);
            $words = explode(" ", $UNOCLOUD_whitelist);
            $this->trim_array($words);
            foreach ($words as $word) {
                $this->saveWord($word, $UNOCLOUD_min_counter, 1, 0, 4);
            }
        }
        if ((!empty($UNOCLOUD_key_whitelist)) && ($this->UNOCLOUD_config->getValue("UNOCLOUD_key_enabled") >
            0)) {
            $keys = explode(",", preg_replace("/[.\-:><()!?\n]/", " ", $UNOCLOUD_key_whitelist));
            $this->trim_array($keys);
            foreach ($keys as $key) {
                $this->saveWord($key, $UNOCLOUD_key_min_counter, 1, 0, 5);
            }
        }
    }

    function setFontSize()
    {
        global $database;
        $UNOCLOUD_max_font = $this->UNOCLOUD_config->getValue("UNOCLOUD_max_font");
        $UNOCLOUD_min_font = $this->UNOCLOUD_config->getValue("UNOCLOUD_min_font");

        $database->setQuery("SELECT max(counter) as 'maxCount', min(counter) as 'minCount' FROM #__unocloud_stat WHERE published=1");

        $maxCount = 0;
        $minCount = 0;
        if ($database->loadObject($row)) {
            $maxCount = $row->maxCount;
            $minCount = $row->minCount;
        }
        if ($UNOCLOUD_min_font <= 0)
            $UNOCLOUD_min_font = 1;
        if ($UNOCLOUD_max_font < $UNOCLOUD_min_font)
            $UNOCLOUD_max_font = $UNOCLOUD_min_font;

        $database->setQuery("SELECT * FROM #__unocloud_stat WHERE published=1 ORDER BY counter DESC");
        if ($rows = $database->loadObjectList()) {
            foreach ($rows as $row) {
                $diff = $maxCount - $minCount;
                if ($diff > 0) {
                    $fontDiff = $UNOCLOUD_max_font - $UNOCLOUD_min_font;
                    $odn = $row->counter - $minCount;
                    $fontSize = $UNOCLOUD_min_font + intval($odn * $fontDiff / $diff);
                } else
                    $fontSize = $UNOCLOUD_min_font;
                $database->setQuery("UPDATE #__unocloud_stat SET fontSize=" . $fontSize .
                    " WHERE word='" . $row->word . "'");
                $database->query();

            }
        }
    }

    function pluginTag($plugin, &$stag, &$metaKey)
    {
        global $mosConfig_absolute_path;
        $runMe = true;
        $loadWord = $this->UNOCLOUD_config->getValue("UNOCLOUD_enabled");
        $loadKey = $this->UNOCLOUD_config->getValue("UNOCLOUD_key_enabled");
        if (is_file($mosConfig_absolute_path .
            "/administrator/components/com_unocloud/plugins/" . $plugin)) {
            if ($this->UNOCLOUD_cache) {
                $stag = null;
                $metaKey = null;
            }
            include ($mosConfig_absolute_path .
                "/administrator/components/com_unocloud/plugins/" . $plugin);
            $this->runTime($plugin);
        } else
            return false;
        return true;
    }


    function loadPlugins(&$stag, &$metaKey)
    {
        global $database;

        $query = "SELECT * FROM #__unocloud_plugins WHERE published=1";
        $database->setQuery($query);
        if ($rows = $database->loadObjectList()) {
            foreach ($rows as $row) {
                $this->pluginTag($row->plugin, $stag, $metaKey);
            }
        }
        return true;
    }

    function checkWord($word, &$excluded)
    {
        $UNOCLOUD_min_len = $this->UNOCLOUD_config->getValue("UNOCLOUD_min_len");
        $UNOCLOUD_max_len = $this->UNOCLOUD_config->getValue("UNOCLOUD_max_len");
        $strlength = Jstring::strlen($word);
        if ($strlength <= $UNOCLOUD_min_len)
            return false;
        if ($strlength >= $UNOCLOUD_max_len)
            return false;
        if (empty($word))
            return false;
        if (!empty($excluded))
            if (in_array($word, $excluded))
                return false;
        return true;
    }

    function checkKey($key, &$excluded)
    {
        $UNOCLOUD_key_min_len = $this->UNOCLOUD_config->getValue("UNOCLOUD_key_min_len");
        $UNOCLOUD_key_max_len = $this->UNOCLOUD_config->getValue("UNOCLOUD_key_max_len");
        $UNOCLOUD_blacklist = $this->UNOCLOUD_config->getValue("UNOCLOUD_blacklist");
        $strlength = Jstring::strlen($key);
        if ($strlength <= $UNOCLOUD_key_min_len)
            return false;
        if ($strlength >= $UNOCLOUD_key_max_len)
            return false;
        if (empty($key))
            return false;
        if (!empty($UNOCLOUD_blacklist))
            if (Jstring::strpos(Jstring::strtolower($UNOCLOUD_blacklist), Jstring::strtolower($key)) !== false)
                return false;
        return true;
    }

    function trim_array(&$arr)
    {
        array_walk($arr, 'UNOCLOUD_trim_value');
    }

    function eraseZeroCounter()
    {
        global $database;
        $database->setQuery("DELETE FROM #__unocloud_stat WHERE published=0 and counter=0");
        $database->query();
    }

    function correctPHPversion()
    {
        if (version_compare(phpversion(), '5.0.0') < 0)
            return false;
        else
            return true;
    }

    function validate(&$stag)
    {
        $stag = strip_tags($stag);

        $replace = array("&nbsp;", "&bdquo;", "&rdquo;", "&ndash;", "&quot;");
        $stag = Jstring::str_ireplace($replace, " ", $stag);

        //begin patch - bug in PHP 4  http://bugs.php.net/bug.php?id=25670
/*        if ((!$this->correctPHP) && (stripos($this->encoding, "UTF-8") !== false)) {
            $stag = $this->UTF_decode($stag);
        } else {*/
        //Чего-то меня смущает закомментированный код.
            $stag = html_entity_decode($stag, ENT_QUOTES, 'UTF-8');

        if (empty($this->UNOCLOUD_preg_replace))
            $stag = preg_replace("/[,.\-:><()!?\n\"'{}]/", " ", $stag);
        else
            $stag = preg_replace($this->UNOCLOUD_preg_replace, " ", $stag);
    }

    function validate_key(&$skey)
    {
        $skey = strip_tags($skey);

        $replace = array("&nbsp;", "&bdquo;", "&rdquo;", "&ndash;", "&quot;");
        $skey = Jstring::str_ireplace($replace, " ", $skey);

        //begin patch - bug in PHP 4 http://bugs.php.net/bug.php?id=25670
/*        if ((!$this->correctPHP) && (stripos($this->encoding, "UTF-8") !== false)) {
            $skey = $this->UTF_decode($skey);
        } else {*/
        //Чего-то меня смущает закомментированный код.
            $skey = html_entity_decode($skey, ENT_QUOTES, 'UTF-8');

        if (empty($this->UNOCLOUD_key_preg_replace))
            $skey = preg_replace("/[.\-:><()!?\n\"']/", " ", $skey);
        else
            $skey = preg_replace($this->UNOCLOUD_key_preg_replace, " ", $skey);

    }

    function resetStat()
    {
        global $database;
        $database->setQuery("UPDATE #__unocloud_stat SET counter=0,type=0");
        $database->query();
    }

    function saveWord($word, $counter, $whitelist_on = 0, $published = 0, $type = 1)
    {
        global $database, $mosConfig_dbprefix;


        $word = Jstring::trim($word);
        $wordLenght = Jstring::strlen($word);
        $database->setQuery("SELECT * FROM #__unocloud_stat WHERE word='" . $word . "'");
        if ($database->loadObject($row)) {
            if (($row->type == 1) && ($type == 2)) {
                $counter += $row->counter; //patch 03-06-2008 - word/key problem
                $type = 3;
            }
            if ($whitelist_on == 1) {
                $database->setQuery("UPDATE #__unocloud_stat SET published=1,type='" . $type .
                    "' WHERE word='" . $word . "'");
                $database->query();
            } else {
                if ($row->counter != $counter) {
                    $database->setQuery("UPDATE #__unocloud_stat SET counter='" . $counter .
                        "', type='" . $type . "' WHERE word='" . $word . "'");
                    $database->query();
                }
            }

        } else {
            if ($whitelist_on == 1)
                $pub = 1;
            else
                $pub = $published;
            $database->setQuery("INSERT INTO #__unocloud_stat (word,counter,published,dateAdd,wordLenght,new,type) VALUES ('" .
                $word . "'," . $counter . ",'" . $pub . "',now(),$wordLenght,1,'" . $type . "')");
            $database->query();
        }
    }
}
?>